// Copyright [2020] <unknown>
#include <bits/stdc++.h>
using namespace std;
// #define ONLINE_JUDGE
#ifndef ONLINE_JUDGE
#define dbg(x...) { cerr << "\033[32;1m" << #x << " -> "; err(x); }
void err() { cerr << "\033[39;0m" << endl; }
template<typename T, typename... A>
void err(T a, A... x) { cerr << a << ' '; err(x...); }
#else
#define dbg(...)
#endif

#define sz(x) ((int)x.size())


const int N = 1e5+50, M = 50;

typedef long long LL;
int  B, bl[N];
vector<int> bcc[N];

inline void update(int &a, int b) {
    a = max(a, b);
}

int n, m, d;


int dp[N * M];

char op[N][M];

vector<int> G[N], G2[N], G3[N];

void add(int u, int v, vector<int> G[]) {
    G[u].push_back(v);
}


bool vis[N][M];
bool tv[N];
int val[N * M];
int c[N][M], tot;
vector<pair<int, int>> path;
void dfs(int u, int j, vector<int> G[], int col) {
    vis[u][j] = 1;
    c[u][j] = col;
    if (op[u][j] == '1' && !tv[u]) {
        tv[u] = 1;
        path.push_back(make_pair(u, j));
        ++val[col];
    }

    for (int v : G[u]) {
        if (!vis[v][(j+1)%d])
            dfs(v, (j+1)%d, G, col);
    }
    // tv[u] = 0;
}

void doit(int bid) {
    for (int bx : bcc[bid])
        for (int j=0; j<d; ++j) 
            if (!vis[bx][j]) {
                // vector<pair<int, int>> path;
                path.clear();
                dfs(bx, j, G2, ++tot);
                for (auto x : path)
                    tv[x.first] = 0;
            }
}

int topo(vector<int> G[]) {
    for (int i=0; i<B; ++i) {
        for (int bx : bcc[i])
            for (int j=0; j<d; ++j) {
                int uc = c[bx][j], u = bx;
                for (int v : G[u]) {
                    int vc = c[v][(j+d-1)%d];
                    update(dp[vc], dp[uc] + val[uc]);
                }
            }
    }
    int cc = c[0][0];
    return dp[cc] + val[cc];
}

pair<int, int> e[N];

namespace tarjan {
    int low[N], dfn[N], clk;
    void init(int n) {
        B = clk = 0;
        memset(dfn, 0, sizeof(int) * (n+1));
        for (int i=0; i<n; ++i) bcc[i].clear();
    }

    void tarjan(int u) {
        static int st[N], p;
        static bool in[N];
        dfn[u] = low[u] = ++clk;
        st[p++] = u; in[u] = true;
        for (int &v : G[u]) {
            if (!dfn[v]) {
                tarjan(v);
                low[u] = min(low[u], low[v]);
            } else if (in[v]) low[u] = min(low[u], dfn[v]);
        }
        if (dfn[u] == low[u]) {
            while (1) {
                int x = st[--p]; in[x] = false;
                bl[x] = B; bcc[B].push_back(x);
                if (x == u) break;
            }
            ++ B;
        }
    }

    void go(int n) {
        init(n);
        for (int i=0; i<n; ++i) {
            if (!dfn[i]) tarjan(i);
        }
    }
}

int main(int argc, char const *argv[]) {
    // code
    scanf("%d%d%d", &n, &m, &d);
    for (int i=0; i<m; ++i) {
        scanf("%d%d", &e[i].first, &e[i].second);
        --e[i].first; --e[i].second;
        add(e[i].first, e[i].second, G);
    }

    for (int i=0; i<n; ++i)
        scanf("%s", op[i]);

    tarjan::go(n);

    for (int i=0; i<m; ++i) {
        int u = e[i].first, v = e[i].second;
        if (bl[u] == bl[v])
            add(u, v, G2);
        else
            add(v, u, G3);
    }

    for (int i=0; i<B; ++i)
        doit(i);

    // for (int i=1; i<=tot; ++i)
    //     dbg(i, val[i]);
    int ans = topo(G3);
    cout << ans << endl;
    return 0;
}
